﻿using huqiang.core.Data;
using huqiang.Core.UIData;
using huqiang.Data;
using System;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.U2D;

namespace huqiang.Core.HGUI
{
    public class ImageLoader
    {
#if UNITY_EDITOR
        static string ImageFolder;
            
#endif
        public virtual bool HandleUrl(HImage image, string texture, string sprite)
        {
#if UNITY_EDITOR
            if(ImageFolder==null)
            {
                INIReader reader = new INIReader();
                reader.LoadFromFile(Environment.CurrentDirectory + "/ProjectSettings/Config.ini");
                var sps = reader.FindOrCreateSection("SpritePackerSetting");
                ImageFolder = sps.GetValue("WorkPath");
                if (ImageFolder == null)
                    ImageFolder = "Assets/AssetsBundle/atlas";
            }
            if (texture.IndexOf("spr:") == 0)
            {
                int e = texture.LastIndexOf('/');
                sprite = texture.Substring(e + 1);
                texture = texture.Substring(4, e - 4);
            }
            string filepath = ImageFolder + "/" + texture+".png";

            if(File.Exists(filepath))
            {
                if(sprite==null)
                {
                    image.MainTexture = UnityEditor.AssetDatabase.LoadAssetAtPath<Texture>(filepath);
                    return true;
                }
                else
                {
                    var ss = UnityEditor.AssetDatabase.LoadAllAssetsAtPath(filepath);
                    if (ss != null)
                    {
                        for (int i = 0; i < ss.Length; i++)
                            if (ss[i].name == sprite)
                            {
                                image.Sprite = ss[i] as Sprite;
                                return true;
                            }
                    }
                    return true;
                }
            }
            else
            {
                if(sprite==null)
                {
                    image.MainTexture = UnityEngine.Resources.Load<Texture>(texture);
                    return image.MainTexture;
                }
                else
                {
                    var ss = UnityEngine.Resources.LoadAll<Sprite>(texture);
                    if (ss != null)
                    {
                        for (int i = 0; i < ss.Length; i++)
                            if (ss[i].name == sprite)
                            {
                                image.Sprite = ss[i];
                                return true;
                            }
                    }
                    return false;
                }
            }
#else
            if (texture.IndexOf("spr:") == 0)
            {
                int e = texture.LastIndexOf('/');
                sprite = texture.Substring(e + 1);
                texture = texture.Substring(4, e - 4);
            }
            if (sprite == null)
            {
                image.MainTexture = UnityEngine.Resources.Load<Texture>(texture);
                return image.MainTexture;
            }
            else
            {
                var ss = UnityEngine.Resources.LoadAll<Sprite>(texture);
                if (ss != null)
                {
                    for (int i = 0; i < ss.Length; i++)
                        if (ss[i].name == sprite)
                        {
                            image.Sprite = ss[i];
                            return true;
                        }
                }
                return false;
            }
#endif
        }
    }
    [Serializable]
    public class HImage : HGraphics
    {
        public static ImageLoader imageLoader;
        public override string TypeName { get =>UIType.HImage; }
        [SerializeField]
        internal Sprite m_sprite = null;
        internal Rect m_rect;
        internal Vector2 m_textureSize;
        internal Vector4 m_border;
        internal Vector2 m_pivot;
        internal int s_id;
        public Sprite Sprite
        {
            get
            {
                return m_sprite;
            }
            set
            {
                m_sprite = value;
                m_dirty = true;
                if (value == null)
                {
                    MainTexture = null;
                    s_id = 0;
                }
                else
                {
                    s_id = value.GetInstanceID();
                    MainTexture = value.texture;
                }
            }
        }
        public HSprite hSprite
        {
            get; set;
        }
        internal void ApplySpriteInfo()
        {
            if (m_sprite != null)
            {
#if UNITY_EDITOR
                s_id = m_sprite.GetInstanceID();
#endif
                m_rect = m_sprite.rect;
                m_textureSize.x = m_sprite.texture.width;
                m_textureSize.y = m_sprite.texture.height;
                m_border = m_sprite.border;
                m_pivot = m_sprite.pivot;
                if (Material != null)
                    Material.SetTexture("_MainTex", m_sprite.texture);
            }
            m_vertexChange = true;
        }
        [SerializeField]
        //[HideInInspector]
        internal SpriteType m_spriteType;
        public SpriteType SprType
        {
            get => m_spriteType; set
            {
                m_spriteType = value;
                m_vertexChange = true;
            }
        }
        [SerializeField]
        [HideInInspector]
        internal FillMethod m_fillMethod;
        public FillMethod FillMethod
        {
            get => m_fillMethod;
            set
            {
                m_fillMethod = value;
                m_vertexChange = true;
            }
        }
        /// <summary>
        /// 逆时针填充
        /// </summary>
        [SerializeField]
        internal bool m_fillClockwise;
        public bool FillClockwise { 
            get => m_fillClockwise;
            set
            {
                m_fillClockwise = value;
                m_vertexChange = true;
            }
        }
        [SerializeField]
        [HideInInspector]
        internal int m_fillOrigin;
        public int FillOrigin
        {
            get => m_fillOrigin; set
            {
                m_fillOrigin = value;
                m_vertexChange = true;
            }
        }

        [SerializeField]
        [HideInInspector]
        internal float m_fillAmount = 1;
        /// <summary>
        /// 填充比例
        /// </summary>
        public float FillAmount
        {
            get => m_fillAmount;
            set
            {
                if (value < 0)
                    value = 0;
                else if (value > 1)
                    value = 1;
                m_fillAmount = value;
                m_vertexChange = true;
            }
        }
        [SerializeField]
        [HideInInspector]
        internal bool m_preserveAspect;
        /// <summary>
        /// 开启此项,按弧度填充,否则按矩形四个角填充
        /// </summary>
        public bool PreserveAspect { get => m_preserveAspect; set => m_preserveAspect = value; }
        [SerializeField]
        [HideInInspector]
        internal float m_pixelsPerUnit = 1;
        internal bool m_fillCenter = true;
        public bool FillCenter
        {
            get { return m_fillCenter; }
            set
            {
                if (m_fillCenter != value)
                    m_vertexChange = true;
                m_fillCenter = value;
            }
        }
        public float PixelsPerUnitMultiplier
        {
            get => m_pixelsPerUnit;
            set
            {
                if (m_pixelsPerUnit != value)
                    m_vertexChange = true;
                m_pixelsPerUnit = value;
            }
        }
        /// <summary>
        /// 使用纹理尺寸
        /// </summary>
        public void SetNativeSize()
        {
            if (m_sprite != null)
            {
                m_sizeDelta.x = m_sprite.rect.width;
                m_sizeDelta.y = m_sprite.rect.height;
            }
        }
        public void SetCircleMask()
        {
            if (m_material == null)
                return;
            if (m_sprite == null)
            {
                m_material.SetVector("_SRect", new Vector4(0.5f, 0.5f, 1, 1));
                return;
            }
            var sp = m_sprite;
            float w = sp.texture.width;
            float h = sp.texture.height;
            float lx = sp.rect.x / w;
            float pw = sp.rect.width / w;
            float cx = lx + pw * 0.5f;
            float dy = sp.rect.y / h;
            float ph = sp.rect.height / h;
            float cy = dy + ph * 0.5f;
            m_material.SetVector("_SRect", new Vector4(cx, cy, pw, ph));
        }
        public override void MainUpdate()
        {
            base.MainUpdate();
            if (m_dirty)
            {
                ApplySpriteInfo();
                m_dirty = false;
            }
        }
        /// <summary>
        /// 更新网格
        /// </summary>
        public override void UpdateMesh()
        {
            if (m_vertexChange)
            {
                HImageMeshHandle.CreateMesh(this);
                m_vertexChange = false;
                m_colorChanged = false;
            }
            else if (m_colorChanged)
            {
                m_colorChanged = false;
                var c = mesh.vertInfo.DataCount;
                if (c > 0)
                {
                    unsafe
                    {
                        HVertex* hv = mesh.vertInfo.Addr;
                        for (int i = 0; i < c; i++)
                            hv[i].color = m_color;
                    }
                }
            }
        }
        public string Url
        {
            set 
            {
                //HSpriteLoader.LoadSprite(_url,(ht)=> { 
                //    if(ht.Url==_url)
                //    {
                //        hSprite = ht;
                //    }
                //});
            }
        }
        public void LoadFromResources(string txtName,string sprName)
        {
            if (sprName==name)
            {
                MainTexture = UnityEngine.Resources.Load<Texture>(txtName);
                m_sprite = null;
            }
            else
            {
                var sprites = UnityEngine.Resources.LoadAll<Sprite>(txtName);
                for (int i = 0; i < sprites.Length; i++)
                    if (sprites[i].name == sprName)
                    {
                        Sprite = sprites[i];
                        return;
                    }
            }
        }
        public void LoadFromAssetsBundle(string url)
        {
            string[] ss = url.Split('/');
            var abs = AssetBundle.GetAllLoadedAssetBundles();
            foreach (var ab in abs)
            {
                if (ab.name == ss[0])
                {
                    if (ss.Length > 2)
                    {
                        if(ss[1].Contains(".spriteatlas"))
                        {
                            var sa = ab.LoadAsset<SpriteAtlas>(ss[1]);
                            if (sa == null)
                                return;
                            Sprite = sa.GetSprite(ss[2]);
                        }
                        else
                        {
                            var sprites = ab.LoadAssetWithSubAssets<Sprite>(ss[1]);
                            if (sprites == null)
                                return;
                            string sprNmae = ss[2];
                            for (int i = 0; i < sprites.Length; i++)
                                if (sprites[i].name == sprNmae)
                                {
                                    Sprite = sprites[i];
                                    return;
                                }
                        }
                    }
                    else if(ss.Length > 1)
                    {
                        MainTexture = ab.LoadAsset<Texture>(ss[1]);
                        m_sprite = null;
                        return;
                    }
                    return;
                }
            }
        }
        string _url;
        Texture webTex;
        public void LoadFromWeb(string url)
        {
            _url = url;
            Sprite = null;
            if (webTex != null)
            {
                UnityEngine.Object.DestroyImmediate(webTex);
                webTex = null;
            }
            var web = UnityWebRequestTexture.GetTexture(url);
            web.SendWebRequest().completed+=(o)=> {
                var uwr = o as UnityWebRequestAsyncOperation;
                if(uwr.webRequest.responseCode==200)
                {
                    if(_url==url)
                    {
                        MainTexture = DownloadHandlerTexture.GetContent(uwr.webRequest);
                        webTex = MainTexture;
                    }
                }
            };
        }
        public void LoadFromFile(string url)
        {
            if(File.Exists(url))
            {
                var dat = File.ReadAllBytes(url);
                Texture2D t2d = new Texture2D(0,0);
                t2d.LoadRawTextureData(dat);
                MainTexture = t2d;
                m_sprite = null;
            }
        }
        public void LoadImage(string abName,string texName,string sprName)
        {
            if(abName!=null)
            {
                if(texName!=null)
                {
                    if (sprName != null)
                    {
                        Sprite = ElementAsset.FindSprite(abName, texName, sprName);
                    }
                    else
                    {
                        Sprite = null;
                        MainTexture = ElementAsset.FindTexture(abName, texName);
                    }
                }
            }
            else
            {
                if (texName != null)
                {
                    if (imageLoader == null)
                    {
                        LoadFromResources(texName,sprName);
                    }else imageLoader.HandleUrl(this, texName, sprName);
                }
            }
        }
        public override void Clear()
        {
            base.Clear();
            if(webTex!=null)
            {
                UnityEngine.Object.DestroyImmediate(webTex);
                webTex = null;
            }
        }
    }
}
